package iusis.util;

import java.util.regex.*;

import my.simplecalculator.CalculatorWithWord.*;

public class Tools {
	public static enum Stat {undefinedStat, number, point, op};	// 미정의, 수, 소수점, 연산자	
	public static enum OpStat {undefinedOperation, plus, minus, multiply, divide, equal};	// + or - or * or / or =	

	//-----------------------------------------------------------------
	/** 
	 * 입력된 단어가 숫자인지 확인
	 * boolean isNumber(String input)
	 * @param input
	 * @return input이 정수이거나 실수이면 true
	 */
	public static boolean isNumber(String input){
		input = removeWhiteSpace(input);		
		return Pattern.matches("^\\d+(\\.\\d+)?$", input);		
	}
	
	/** 
	 * 입력된 단어가 소숫점인지 확인
	 * boolean isNumber(String input)
	 * @param input
	 * @return input에 소숫점이 1개만 존재하면 true
	 */
	public static boolean isPoint(String input){
		input = removeWhiteSpace(input);
		return Pattern.matches("\\d*\\.\\d*", input);		
	}
	
	/**
	 * 입력된 단어가 연산자인지 확인
	 * boolean isOp(String input)
	 * @param word
	 * @return input이 "+" or "-" or "*" or "/" or "=" 이면 true
	 */
	public static boolean isOp(String word){
		word = removeWhiteSpace(word);		
		return Pattern.matches("[\\+\\-\\*\\/\\=]", word);
	}
	
	/**
	 * 입력된 단어가 어느 Stat인지 확인
	 * Stat whichStat(String input)
	 * @param word
	 * @return input이 어느 Stat인지 확인 (undefined, number, point, op)
	 */
	public static Stat whichStat(String word){

		Stat resultStat = Stat.undefinedStat;
		
		word = word.trim();
		
		if(isNumber(word))
		{
			resultStat = Stat.number;			
		}
		else if(isPoint(word)){			
			resultStat = Stat.point;			
		}
		else if(isOp(word)){
			resultStat = Stat.op;			
		}
		return resultStat;
	}
	
	/**
	 * 입력된 연산자의 종류를 확인
	 * @param word
	 * @return  "+" or "-" or "*" or "/" or "="
	 */
	public static OpStat whichOp(String word){
		OpStat resultStat = OpStat.undefinedOperation;
		if(isOp(word)){ 
			word = word.trim();
			if(word.equals("+")){
				resultStat = OpStat.plus;
			}
			else if(word.equals("-")){
				resultStat = OpStat.minus;
			}
			else if(word.equals("*"))	{
				resultStat = OpStat.multiply;
			}
			else if(word.equals("/"))	{
				resultStat = OpStat.divide;
			}
		}
		return resultStat;
	}

	
	//-----------------------------------------------------------------	
	
	/**
	 * 주어진 연산식에서 연산자 좌우에 공백문자를 추가함
	 * @param expr
	 * @return 공백문자가 추가된 스트링
	 */
	private static String fillWhiteSpace(String expr){
		char [] str = expr.toCharArray();
		String result = "";		
		for(int i=0; i<str.length; i++){
			char ch = str[i];
			switch(ch){
			case '+':
			case '-':
			case '*':
			case '/':
			case '=':
				result = result+" "+ch+" ";
				break;
			default:
				result += str[i];
			}
		}		
		return result;
	}//
	
	/**
	 * 주어진 연산식에서 공백문자를 제거함
	 * @param inputstring
	 * @return 공백문자를 없앤 스트링
	 */
	public static String removeWhiteSpace(String inputstring){
		inputstring = inputstring.replaceAll("\\p{Space}", "");		
		return inputstring;
	}
	
	/**
	 * 주어진 사칙연산식을 단어별로 쪼갠 스트링 배열을 반환
	 * @param expr
	 * @return 식의 스트링 배열을 반환
	 */
	public static String[] parseOriginalExpr(String originalExpr){
		String result = Tools.fillWhiteSpace(originalExpr);
		return result.split("\\p{Space}");
	}//
	
	/**
	 * 주어진 식이 유효한지 체크
	 * @param expr
	 * @return 유효한 식이면 true, 아니면 false 반환
	 */
	public static boolean isValidExpr(String expr){
		expr = Tools.removeWhiteSpace(expr);
		return expr.matches("\\d+(\\.\\d+)?([\\+|\\-|\\*|\\/|\\=](\\d+(\\.\\d+)?))+");
	}
	
	/**
	 * 주어진 단어가 유효한지 체크
	 * @param expr
	 * @return 유효한 단어이면 true, 아니면 false 반환
	 */
	public static boolean isValidWord(String word){	
		Stat stat = whichStat(word);		
		return (stat!=Stat.undefinedStat);
	}
}
